/*
Copyright (C) 2003  Pierrick Brihaye
pierrick.brihaye@wanadoo.fr
 
Original Perl code :
Portions (c) 2002 QAMUS LLC (www.qamus.org), 
(c) 2002 Trustees of the University of Pennsylvania 
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the
Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
or connect to:
http://www.fsf.org/copyleft/gpl.html
*/

package gpl.pierrick.brihaye.aramorph;

import gpl.pierrick.brihaye.util.LRUCache;

import java.util.Iterator;

/** An in-memory dictionary of prefixes, stems, suffixes and combinations fed with
 * resources avalaible in the classpath.
 *@author Pierrick Brihaye, 2003
 */
class DictionaryHandler{
	/**A logger to write log messages*/
//	private static Logger logger = Logger.getLogger(DictionaryHandler.class.getName());
	/** InMemoryDictionary of prefixes */
	private Dictionary prefixes;
	/** InMemoryDictionary of stems */
	private Dictionary stems;
	/** InMemoryDictionary of suffixes */
	private Dictionary suffixes;
	/** Compatibility table for prefixes-stems combinations.*/
	private CompatibilityTable tableAB;
	/** Compatibility table for prefixes-suffixes combinations.*/
	private CompatibilityTable tableAC;
	/** Compatibility table for stems-suffixes combinations.*/
	private CompatibilityTable tableBC;

	/**A cache for found entries for fast access*/
	protected LRUCache<String, Boolean> found_entries;
	
	/**
	 * Constructs a new DicitionaryHandler using the given dictionaries and compatibility tables
	 * @param prefixes
	 * @param stems
	 * @param suffixes
	 * @param tableab
	 * @param tableac
	 * @param tablebc
	 */
	public DictionaryHandler(Dictionary prefixes, Dictionary stems,
			Dictionary suffixes, CompatibilityTable tableab,
			CompatibilityTable tableac, CompatibilityTable tablebc,
			int cacheSize) {
		this.prefixes = prefixes;
		this.stems = stems;
		this.suffixes = suffixes;
		this.tableAB = tableab;
		this.tableAC = tableac;
		this.tableBC = tablebc;
		
		this.found_entries = new LRUCache<String, Boolean>(cacheSize);
	}
	
	/**
	 * Constructs a new DicitionaryHandler using the given dictionaries and compatibility tables
	 * @param prefixes
	 * @param stems
	 * @param suffixes
	 * @param tableab
	 * @param tableac
	 * @param tablebc
	 */
	public DictionaryHandler(Dictionary prefixes, Dictionary stems,
			Dictionary suffixes, CompatibilityTable tableab,
			CompatibilityTable tableac, CompatibilityTable tablebc) {
		this(prefixes, stems, suffixes, tableab,tableac,tablebc, 1000);
	}
	
	/** Whether or not the prefix is in the dictionary.
	 * @param translitered The prefix
	 * @return The result
	 */
	public boolean hasPrefix(String translitered) {
		String key = "p/"+translitered;
		boolean found;
		if (this.found_entries.containsKey(key))
			found = true;
		else {
			found = this.prefixes.contains(translitered);
			if (found)
				this.found_entries.put(key,true);
		}
		return found;
	}
	
	/** Returns an iterator on the solutions for the given prefix.
	 * @param translitered The prefix
	 * @return The iterator
	 */
	public Iterator<DictionaryEntry> getPrefixIterator(String translitered) {
		return prefixes.getIterator(translitered);
	}
	
	/** Whether or not the stem is in the dictionary.
	 * @param translitered The stem
	 * @return The result
	 */
	public boolean hasStem(String translitered) {
		String key = "t/"+translitered;
		boolean found;
		if (this.found_entries.containsKey(key))
			found = true;
		else {
			found = stems.contains(translitered);
			if (found)
				this.found_entries.put(key,true);
		}
		return found;
	}
	
	/** Returns an iterator on the solutions for the given stem.
	 * @param translitered The stem
	 * @return The iterator
	 */
	public Iterator<DictionaryEntry> getStemIterator(String translitered) {
		return stems.getIterator(translitered);
	}
	
	public Iterator<DictionaryEntry> getStemIteratorByGloss(String gloss){
		return stems.getIteratorForGloss(gloss);
	}
	
	/** Whether or not the suffix is in the dictionary.
	 * @param translitered The suffix
	 * @return The result
	 */
	public boolean hasSuffix(String translitered) {
		String key = "s/"+translitered;
		boolean found;
		if (this.found_entries.containsKey(key))
			found = true;
		else {
			found = suffixes.contains(translitered);
			if (found)
				this.found_entries.put(key,true);
		}
		return found;
		
	}
	
	/** Returns an iterator on the solutions for the given suffix.
	 * @param translitered The suffix
	 * @return The iterator
	 */
	public Iterator<DictionaryEntry> getSuffixIterator(String translitered) {
		return suffixes.getIterator(translitered);
	}
	
	/** Whether or not the prefix/stem combination is possible.
	 * @param AB The prefix and stem combination.
	 * @return The result
	 */
	public boolean hasAB(String A, String B) {
		return tableAB.contains(A,B);
	}
	
	/** Whether or not the prefix/suffix combination is possible.
	 * @param AC The prefix and suffix combination.
	 * @return The result
	 */
	public boolean hasAC(String A, String C) {
		return tableAC.contains(A,C);
	}
	
	/** Whether or not the stem/suffix combination is possible.
	 * @param BC The stem and suffix combination.
	 * @return The result
	 */
	public boolean hasBC(String B, String C) {
		return tableBC.contains(B,C);
	}
}